﻿/*
 * Copyright (c) 2011 Shawn Rakowski
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to 
 * deal in the Software without restriction, including without limitation the 
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 
 * sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in 
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
 * SOFTWARE. 
 * 
 */

using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ROS.Application.DomainObjects;
using ROS.Persistence;
using ROS.Application.DTO;

namespace ROS.Application
{
    internal class MenuService
    {
        #region Fields

        MenuCategoryDataMapper menuCategoryDataMapper;
        MenuItemDataMapper menuItemDataMapper;

        #endregion

        #region Properties

        #endregion

        #region Constructor

        /// <summary>
        /// Construct a new MenuService object.
        /// </summary>
        internal MenuService()
        {
            menuCategoryDataMapper = new MenuCategoryDataMapper();
            menuItemDataMapper = new MenuItemDataMapper();
        }

        #endregion

        #region Methods

        #region Menu Categories

        /// <summary>
        /// Creates a new MenuCategory.
        /// </summary>
        /// <param name="categoryName"></param>
        /// <returns>Menu Category ID</returns>
        internal long AddMenuCategory(String categoryName)
        {
            MenuCategory menuCategory = new MenuCategory(categoryName);
            menuCategoryDataMapper.Create(menuCategory);
            return menuCategory.ID;
        }

        /// <summary>
        /// Get a list of menu categories.
        /// </summary>
        /// <returns></returns>
        internal ROSStatus GetMenuCategories(out IList<MenuCategoryDTO> menuCategoryDTOs)
        {
            menuCategoryDTOs = new List<MenuCategoryDTO>();
            IList<MenuCategory> menuCategories = menuCategoryDataMapper.FindAll();
            foreach (MenuCategory menuCategory in menuCategories)
                menuCategoryDTOs.Add(MapMenuCategoryToDTO(menuCategory));
            return ROSStatus.SUCCESS;
        }

        /// <summary>
        /// Delete a menu category.
        /// </summary>
        /// <param name="menuCategoryID"></param>
        internal void DeleteMenuCategoryByID(long menuCategoryID)
        {
            menuCategoryDataMapper.Delete(menuCategoryID);
        }

        /// <summary>
        /// Map a Menu Category object to a DTO that can be used by the presentation tier.
        /// </summary>
        /// <param name="menuItem"></param>
        /// <returns></returns>
        private MenuCategoryDTO MapMenuCategoryToDTO(MenuCategory menuCategory)
        {
            MenuCategoryDTO menuCategoryDTO = new MenuCategoryDTO();
            menuCategoryDTO.ID = menuCategory.ID;
            menuCategoryDTO.Name = menuCategory.Name;
            return menuCategoryDTO;
        }

        #endregion

        #region Menu Items

        /// <summary>
        /// Add a new menu item.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="isBackendFulfilled"></param>
        /// <param name="price"></param>
        /// <param name="categoryIDs"></param>
        /// <returns>Menu Item ID</returns>
        internal long AddMenuItem(String name, bool isBackendFulfilled,
                                   decimal price, IList<long> categoryIDs)
        {            
            Money menuItemPrice = new Money(price, Currency.USD); // refactor currency out later.

            List<MenuCategory> menuCategories = new List<MenuCategory>();
            foreach (int categoryID in categoryIDs)
            {
                menuCategories.Add(menuCategoryDataMapper.FindByID(categoryID));
            }

            MenuItem menuItem = new MenuItem(name, isBackendFulfilled, menuItemPrice, menuCategories);

            menuItemDataMapper.Create(menuItem);

            return menuItem.ID;
        }

        internal IList<MenuItemDTO> GetMenuItems()
        {
            IList<MenuItem> menuItems = menuItemDataMapper.FindAll();
            List<MenuItemDTO> menuItemDTOs = new List<MenuItemDTO>();
            foreach (MenuItem menuItem in menuItems)
            {
                if (menuItem.IsActive)
                {
                    menuItemDTOs.Add(mapMenuItemToDTO(menuItem));
                }
            }
            return menuItemDTOs;
        }

        internal void DeleteMenuItemByID(long menuItemID)
        {
            MenuItem menuItem = menuItemDataMapper.FindByID(menuItemID);
            if (menuItem.MayBeDeleted)
            {
                menuItemDataMapper.Delete(menuItem);
            }
            else
            {
                menuItem.Deactivate();
                menuItemDataMapper.Update(menuItem);
            } 
        }

        internal ROSStatus GetMenuItemsByCategory(long categoryID, out IList<MenuItemDTO> menuItemDTOs)
        {
            MenuCategory menuCategory = menuCategoryDataMapper.FindByID(categoryID);

            IList<MenuItem> menuItems = menuItemDataMapper.FindAllByCategory(menuCategory);
            
            menuItemDTOs = new List<MenuItemDTO>();
            foreach (MenuItem menuItem in menuItems)
                menuItemDTOs.Add(mapMenuItemToDTO(menuItem));
            
            return ROSStatus.SUCCESS;
        }

        private MenuItemDTO mapMenuItemToDTO(MenuItem menuItem)
        {
            MenuItemDTO menuItemDTO = new MenuItemDTO();
            menuItemDTO.ID = menuItem.ID;
            menuItemDTO.Name = menuItem.Name;
            menuItemDTO.Price = menuItem.Price.ToString();
            menuItemDTO.IsBackendFulfilled = menuItem.IsBackendFulfilled;
            return menuItemDTO;
        }

        #endregion

        #endregion
    }
}
